import { shallowReactive, isProxy } from 'vue'
/**
 *
 * @param arr 需要分组数组
 * @param fun 获取key函数
 * @returns
 */
function group<T, K>(arr: Array<T>, fun: Fun<T, K>, keyIdFun: Fun<K, any> = (k1: K) => k1): Array<GroupEntity<K, T>> {
    let res: Array<GroupEntity<K, T>> = []
    let mapHelper = new Map<any, Array<T>>()
    let entityMapHelper = new Map<any, K>()
    arr.forEach((v) => {
        let entity = fun(v)
        let key = keyIdFun(entity)
        entityMapHelper.set(key, entity)
        let arr = mapHelper.get(key)
        if (arr) {
            arr.push(v)
        } else {
            arr = []
            arr.push(v)
            mapHelper.set(key, arr)
        }
    })
    res = Array.from(mapHelper.entries()).map((v) => ({ key: entityMapHelper.get(v[0])!, val: v[1] }))
    return res
}

type Enums = {
    id: number
    text: string
}
/**
 * 获取枚举文本
 * @param enums
 * @param id
 * @returns
 */
function getTextByEnum(enums: Array<Enums>, id: number): string {
    return enums.find((v) => v.id == id)?.text || ''
}

function strengthenShallowReactive<T extends { [n: string]: any }>(target: T, deep: number = 1) {
    if (deep > 1) {
        Object.keys(target).forEach((key) => {
            let val: any = target[key]
            if (val && isCommonObject(val)) {
                target[key as keyof T] = strengthenShallowReactive(val)
            }
        })
    }
    let res = shallowReactiveWithCollection(target)
    return res
}

function shallowReactiveWithCollection<T extends { [n: string]: any }>(target: T) {
    Object.keys(target).forEach((key) => {
        let val: any = target[key]
        if (val && (val instanceof Array || val instanceof Set || val instanceof Map)) {
            target[key as keyof T] = shallowReactive(val) as any
        }
    })
    let res = shallowReactive(target)
    return res
}

function isCommonObject(val: any): boolean {
    let collect = val instanceof Array || val instanceof Set || val instanceof Map
    if (!collect && !isProxy(val) && typeof val == 'object') {
        return true
    }
    return false
}

function deepCopy<T>(target: T): T {
    return JSON.parse(JSON.stringify(target))
}

function splitArray<T>(array: T[], range: number): Array<T[]> {
    let res: Array<T[]> = []
    for (let i = 0; i < array.length; i = i + range) {
        let temp: Array<T> = []
        for (let j = 0; j < range; j++) {
            let index = i + j
            if (index < array.length) {
                temp.push(array[index])
            }
        }
        res.push(temp)
    }
    return res
}

export default {
    group,
    getTextByEnum,
    strengthenShallowReactive,
    deepCopy,
    splitArray
}
